package game.assets;

import haxe.io.Encoding;
import game.data.ProjectDataExport;
import game.data.Hxwz2RolePackageData;
import hx.core.OpenFLSound;
import hx.assets.XmlAtlas;
import hx.events.FutureErrorEvent;
import openfl.events.IOErrorEvent;
import openfl.events.Event;
import openfl.media.Sound;
import hx.assets.Assets;
import haxe.io.Path;
import hx.core.OpenFlBitmapData;
import hx.display.BitmapData;
import hx.assets.Zip;
import haxe.Exception;
import haxe.io.Bytes;
import hx.assets.Future;

/**
 * 幻想纹章2角色包资源加载器，用于加载旧版本的角色包.data，请注意此加载方式，可能会丢失一定的战斗数据，请测试好相关角色内容
 */
class Hxwz2RolePackageFuture extends Future<RoleAssets, String> {
	public var zip:Zip;

	public var keepZip:Bool = false;

	public function new(path:String, keepZip:Bool = false) {
		super(path, false);
		this.keepZip = keepZip;
	}

	override function post() {
		super.post();
		// 二进制加载器进行载入角色包
		new hx.core.BytesFuture(this.getLoadData()).onComplete(data -> {
			// 对角色包进行解压处理
			var zip = new Zip(data);
			zip.unzip();
			if (keepZip) {
				this.zip = zip;
			}
			// 先兼容检测一下是预览包还是正式包
			checkCode(zip.entrys.get("content.png").data, code, (bool) -> {
				if (bool) {
					this.startLoad(zip);
				} else {
					code = "20160707";
					checkCode(zip.entrys.get("content.png").data, code, (bool) -> {
						if (bool) {
							this.startLoad(zip);
						} else {
							this.errorValue(FutureErrorEvent.create(FutureErrorEvent.LOAD_ERROR, -1, "角色包无法被解析"));
						}
					});
				}
			});
		}).onError(error -> {});
	}

	private function checkCode(bytes:Bytes, code:String, cb:Bool->Void):Void {
		openfl.display.BitmapData.loadFromBytes(decode(bytes)).onComplete((data) -> {
			cb(true);
		}).onError(error -> {
			cb(false);
		});
	}

	private function startLoad(zip:Zip) {
		trace("使用编译code", code);
		var assets:RoleAssets = new RoleAssets();
		var pngs:Map<String, BitmapData> = new Map();
		var pngError:Map<String, Bool> = [];
		var xmls:Map<String, Xml> = new Map();
		var keys = zip.entrys.keys();
		/**
		 * 逐个加载角色资源，旧版本人物包，只有音效、精灵图、角色战斗数据xml三种
		 */
		function load():Void {
			if (keys.hasNext()) {
				var s = keys.next();
				var data = zip.readBytes(s);
				var decodeData = decode(data);
				var ext = Path.extension(s).toLowerCase();
				switch ext {
					case "mp3":
						// 加载音频
						var sound = new Sound();
						sound.addEventListener(Event.COMPLETE, (e:Event) -> {
							var hxSound = new hx.assets.Sound();
							hxSound.root = new OpenFLSound(sound);
							assets.sounds.set(Assets.formatName(s), hxSound);
							// trace("载入音频", s);
							load();
						});
						sound.addEventListener(IOErrorEvent.IO_ERROR, (e:IOErrorEvent) -> {
							this.errorValue(FutureErrorEvent.create(FutureErrorEvent.LOAD_ERROR, -1, "load fail:" + s));
						});
						try {
							sound.loadCompressedDataFromByteArray(decodeData, decodeData.length);
						} catch (e:Exception) {
							trace(e.message, "skip", s);
							load();
						}
					case "png":
						// 加载精灵图
						openfl.display.BitmapData.loadFromBytes(decodeData).onComplete((data) -> {
							if (data != null) {
								var bitmapData = hx.display.BitmapData.formData(new OpenFlBitmapData(data));
								pngs.set(Assets.formatName(s), bitmapData);
								load();
							} else {
								// this.errorValue(FutureErrorEvent.create(FutureErrorEvent.LOAD_ERROR, -1, "formData fail:" + s));
								pngError.set(Path.withoutExtension(s), true);
								load();
							}
						}).onError((err) -> {
							this.errorValue(FutureErrorEvent.create(FutureErrorEvent.LOAD_ERROR, -1, "load fail:" + s));
						});
					case "gif":
						// 忽略
						load();
					case "xml", "data":
						// 加载精灵图xml，或者角色数据
						// trace("xml.decodeData", s, decodeData.toString());
						var xml = Xml.parse(decodeData.toString());
						xmls.set(Assets.formatName(s), xml);
						load();
					default:
						trace("unknown file type:" + s);
						load();
				}
			} else {
				// 这里要开始解析精灵图
				for (key => xml in xmls) {
					if (pngs.exists(key)) {
						// trace("载入图集", key);
						var png = pngs.get(key);
						try {
							var atlas = new XmlAtlas(png, xml);
							atlas.parser();
							assets.atlases.set(key, atlas);
						} catch (e:Exception) {
							trace("载入图集失败", e.message);
							trace(xml.toString());
							continue;
						}
					}
				}
				// 载入角色图集
				var content = pngs.get("content");
				var role = xmls.get("role");
				var atlas = Xml.createDocument();
				var root = Xml.createElement("TextureAtlas");
				atlas.addChild(root);
				for (action in role.firstElement().elements()) {
					if (action.nodeName == "act") {
						// 解析精灵图
						for (item in action.elements()) {
							root.insertChild(Xml.parse(item.toString()).firstElement(), 0);
						}
					}
				}
				var atlasObject = new XmlAtlas(content, atlas);
				atlasObject.parser();
				assets.atlases.set("content", atlasObject);
				assets.data = new Hxwz2RolePackageData(role);

				// 将不再需要的资源图片引用删除
				for (data in assets.data.actions) {
					for (frame in data.frames) {
						var i = frame.effects.length;
						while (i-- > 0) {
							var effect = frame.effects[i];
							if (pngError.exists(effect.name)) {
								frame.effects.remove(effect);
							}
						}
					}
				}

				this.completeValue(assets);
			}
		}
		load();
	}

	public var code:String = "99390298351126";

	/**
	 * 包体解密处理
	 * @param rootBytes 
	 * @return Bytes
	 */
	public function decode(rootBytes:Bytes):Bytes {
		var code:Int = Std.parseInt(code);
		var newBytes:Bytes = Bytes.alloc(rootBytes.length);
		var len = rootBytes.length;
		var p:Int = 0;
		for (i in 0...len) {
			p = i;
			try {
				newBytes.set(i, rootBytes.get(i) - code);
			} catch (e:Exception) {
				throw e;
			}
		}
		return newBytes;
	}
}
